/*:
 * @plugindesc 枫之舞界面 - 战斗角色图位置
 * @author 老饕
 * @version 1.0.0
 * @date 2020.12.16

 * @help
 * 把SV战斗图运动方式位置改成FV。
 * 战斗图增加透视效果。
 * 修正一些战斗行动效果。
*/
let SWDA_BattlerSpritesPosition =  {};

// 敌人
Sprite_Enemy.prototype.stepForward = function() {
    this.startMove(0, Yanfly.Param.BECStepDist, 12);
};


Sprite_Battler.prototype.stepToSubstitute = function(focus) {
    var target = focus.battler();
    var targetX = (this.x - this._homeX) + (target._homeX - this._homeX);
    var targetY = (this.y - this._homeY) + (target._homeY - this._homeY);;
    if (focus.isActor()) targetX -= this._mainSprite.width / 2;
    if (focus.isEnemy()) targetX += this.width / 2;
    this.startMove(targetX, targetY, 1);
};

Sprite_Battler.prototype.stepFlinch = function() {
    var flinchX = this.x - this._homeX - (this.x - Graphics.boxWidth/2) * 0.1;
    var flinchY = this.y - this._homeY - Yanfly.Param.BECFlinchDist;
    this.startMove(flinchX, flinchY, 6);
};


// 敌人后退时不再镜像
//Game_Enemy.prototype.spriteFaceBackward = function() {
//    this.setMirror(false);
//};


// 角色不再根据目标点镜像

Game_Battler.prototype.spriteFacePoint = function(pointX, pointY) {
    this.spriteFaceForward();
};

Game_Battler.prototype.spriteFaceAwayPoint = function(pointX, pointY) {
     this.spriteFaceBackward();
};

Game_Actor.prototype.spriteFacePoint = function(pointX, pointY) {
	this.spriteFaceForward();
};

Game_Actor.prototype.spriteFaceAwayPoint = function(pointX, pointY) {
    this.spriteFaceBackward();
};



// 目标为自身时（含逃跑等），不再向前（但是闪烁）
Game_Battler.prototype.performActionStart = function(action) {
    if (!action.isGuard()) {
		if (!action.isForUser()){
			this.setActionState('acting');
			this.spriteStepForward();
		}else{
			this.requestEffect('whiten');
		}
    }
};

//==========================================================
// 在敌群事件中，指定敌人坐标信息
//==========================================================
SWDA_BattlerSpritesPosition.Game_Troop_Setup = Game_Troop.prototype.setup;
Game_Troop.prototype.setup = function(troopId){
	SWDA_BattlerSpritesPosition.Game_Troop_Setup.call(this, troopId);
	this.setupEnemyPosition();
};
Game_Troop.prototype.setupEnemyPosition = function(){
	const page = this.troop().pages[0];

	// 按敌群编号配置（从1开始）
	const regX = /<Enemy Position X: ([\S\s]+)>/;
	const regY = /<Enemy Position Y: ([\S\s]+)>/;
	const regAnchorY = /<Enemy Anchor Y: ([\S\s]+)>/;
	const regEdgeLimit =  /<Enemy Edge Limit: ([\S\s]+)>/;

	page.list.forEach(function(ev){
		if([108, 408].contains(ev.code)){
			// 按敌群编号配置（从1开始）
			if(regX.exec(ev.parameters[0]) ){
				let memberId = Number(RegExp.$1.trim().split(",")[0]);
				let x = Number(RegExp.$1.trim().split(",")[1]);
				this.members()[memberId - 1].setHomeX(x);
			}
			if(regY.exec(ev.parameters[0]) ){
				let memberId = Number(RegExp.$1.trim().split(",")[0]);
				let y = Number(RegExp.$1.trim().split(",")[1]);
				this.members()[memberId - 1].setHomeY(y);
			}
			if(regAnchorY.exec(ev.parameters[0]) ){
				let memberId = Number(RegExp.$1.trim().split(",")[0]);
				let anchorY =Number( RegExp.$1.trim().split(",")[1]);
				this.members()[memberId - 1].setAnchorY(anchorY);
			}
			if(regEdgeLimit.exec(ev.parameters[0]) ){
				let memberId = Number(RegExp.$1.trim().split(",")[0]);
				this.members()[memberId - 1].setEdgeLimit();
			}
		}
	}, this);
};

//=========================================================
// 敌人坐标信息修改
//=========================================================
Game_Enemy.prototype.setHomeX = function(x) {
	this._homeXset = x;
};

Game_Enemy.prototype.setHomeY = function(y) {
	this._homeYset = y;
};

Game_Enemy.prototype.setAnchorY = function(anchorY) {
	this._anchorYset = anchorY;
};

Game_Enemy.prototype.setEdgeLimit = function() {
	this._edgeLimit = true;
};
// 覆写anchorY：在人为设置纵坐标后读取该设置值。
Game_Battler.prototype.spritePosY = function() {
	if (this.battler()) {
      return this.battler().y + this.spriteHeight() * (1-this.battler().anchor.y);
    } else {
      return 0;
    }
};
// 覆写anchorY：在人为设置锚点后读取该设置值。
Game_Battler.prototype.anchorY = function() {
	if(this._anchorYset)
    	return this._anchorYset;
	else
		return Yanfly.Param.BECAnchorY;
};

//=========================================================
// 敌人重定位
//=========================================================

// home位置（根据分辨率调整，并整体上移）
SWDA_BattlerSpritesPosition.Sprite_Enemy_SetHome = Sprite_Enemy.prototype.setHome;
Sprite_Enemy.prototype.setHome = function(x,y) {
	SWDA_BattlerSpritesPosition.Sprite_Enemy_SetHome.call(this,x,y);
	var newResX = 960;			// 期望扩展宽度：若希望均匀分布全屏，则：Graphics.boxWidth;，若希望保留原始尺寸，则816。按枫之舞原作比例则960
	var dX = newResX / 816;		// 期望分辨率/当前分辨率（1280）
	var dY = Graphics.boxHeight / 624;
	y = y * dY - 32;			// 之后还会被yep_core进行修正
	x = x * dX + (Graphics.boxWidth - newResX)/2;
	this._homeX = x;
	this._homeY = y;
	this.resetHome();
};

// 重设Home(敌群注释，或代码手动对Game_Enemy设置后开启home刷新标志)
Sprite_Enemy.prototype.resetHome = function() {
	if (this._enemy._homeXset !== undefined)
		this._homeX = this._enemy._homeXset;

	if (this._enemy._homeYset !== undefined)
		this._homeY = this._enemy._homeYset;

	if (this._enemy._anchorYset !== undefined)
		this.anchor.y = this._enemy._anchorYset;

	this._requestUpdateHome = true;
};

SWDA_BattlerSpritesPosition.Sprite_Enemy_update= Sprite_Enemy.prototype.update;
Sprite_Enemy.prototype.update = function(){
	SWDA_BattlerSpritesPosition.Sprite_Enemy_update.call(this);
	this.updateHome();
};
Sprite_Enemy.prototype.realY = function(){
	return this.y + this._enemy.spriteHeight() * (1-this.anchor.y);
};

// 覆写：YEP_X_ActSeqPack2（Sprite_Battler.prototype.updateFloat）
Sprite_Enemy.prototype.updateFloat = function() {
    if (!this._battler) return;
    if (this._floatDur > 0) this._floatDur--;
    if (this._jumpDur > 0) this._jumpDur--;
    var baseY = this._battler.anchorY();
    var floatHeight = this.getFloatHeight();
    var jumpHeight = this.getJumpHeight();
    var height = floatHeight + jumpHeight;
    if (this._mainSprite && this._mainSprite.bitmap) {
      var rate = this._battler.spriteHeight() / this._mainSprite.height;
      this._mainSprite.anchor.y = (baseY + height * rate);
      this._weaponSprite.anchor.y = this._mainSprite.anchor.y;
    } else {
		if (this._enemy._anchorYset !== undefined)
			this.anchor.y = this._enemy._anchorYset;	// 这里校正
		else
      		this.anchor.y = (baseY + height);
    }
};

// 新增：更新选择区域（敌人窗口大小、位置等）
Sprite_Enemy.prototype.updateVisualSelectArea = function() {
	//if (this._visualSelectWindow){
		//if (SceneManager._scene._statusWindow)
		this._visualSelectWindow.updateWindowSize();
		this._visualSelectWindow.updateWindowPosition();
		this._visualSelectWindow.makeWindowBoundaries();
	//}
}

Sprite_Enemy.prototype.updateHome = function() {
	if (this._requestUpdateHome && this.bitmap.isReady()){
		const spriteHeight = this._enemy.spriteHeight() * this.anchor.y;
		const floatingDelta = this._enemy.isFloating() ? 2 * this._enemy.floatRate() * spriteHeight + this._enemy.floatHeight() : 0;
		// 呼吸校正：如果是限制边缘的情况，应上移保证边缘不露出。否则应下移保证战斗图完全显示。
		const breathingDelta = this._enemy.isBreathing() ? 
			((this._enemy._edgeLimit) ?
				 -this._enemy.breathYRate() * spriteHeight : this._enemy.breathYRate() * spriteHeight)
			 : 0;
		if (this._homeY - spriteHeight - floatingDelta - breathingDelta < 0){
			this._homeY = spriteHeight + floatingDelta + breathingDelta;
		}
		this.updateVisualSelectArea();
		this._requestUpdateHome = false;
	}
};

// 缩放
SWDA_BattlerSpritesPosition.Sprite_Enemy_Update = Sprite_Enemy.prototype.update
Sprite_Enemy.prototype.update = function() {
    SWDA_BattlerSpritesPosition.Sprite_Enemy_Update.call(this);
    if (this._svBattlerEnabled) this.updateMotion();
    this.updatePerspectiveScale();
	this.fixY();
	this.fixX();
};

// 更新透视尺度
Sprite_Enemy.prototype.updatePerspectiveScale = function() {
	this.scale.x *= this.perspectiveScale();
	this.scale.y *= this.perspectiveScale();

};

// 计算敌人透视尺度
Sprite_Enemy.prototype.perspectiveScale = function() {
	// 后退0.002，前进0.001，如果有边缘限制，则后退不变尺度。
	if (this.y < this._homeY){
		if (this._enemy._edgeLimit){
				return 1;
		}else{
			return 1 + Math.round((this.y - this._homeY)) * 0.003;
		}
	}
	return 1 + Math.round((this.y - this._homeY)) * 0.001;
};


Sprite_Enemy.prototype.fixY = function() {
	// 吊顶的情况：保证在缩放、移动后，y始终为0）
	if (this._homeY == 0 && this.anchor.y == 0){
		this.y = 0;
	}
}

Sprite_Enemy.prototype.fixX = function() {
	// 两侧限制的情况
	if (this._enemy._edgeLimit){
		if (this.scale.x * this._enemy.spriteWidth() >= Graphics.boxWidth){
			this.x = this.x.clamp(Graphics.boxWidth - this.scale.x * this._enemy.spriteWidth() * this.anchor.x,
				this.scale.x * this._enemy.spriteWidth() * (1 - this.anchor.x))
		}
		this.y = Math.min(this.y, this.scale.y * this._enemy.spriteHeight() * this.anchor.y)

	}
}

//=========================================================
// 角色
//=========================================================
Sprite_Actor.prototype.stepForward = function() {
    this.startMove(0, -Yanfly.Param.BECStepDist, 12);
};

Sprite_Actor.prototype.retreat = function() {
    this.startMove(0, 300, 30);
};


Sprite_Actor.prototype.stepFlinch = function() {
    var flinchX = this.x - this._homeX + (this.x - Graphics.boxWidth / 2) * 0.05;
    var flinchY = this.y - this._homeY + (Yanfly.Param.BECFlinchDist);
    this.startMove(flinchX, flinchY, 12);
};

SWDA_BattlerSpritesPosition.Sprite_Actor_updateBitmap = Sprite_Actor.prototype.updateBitmap;
Sprite_Actor.prototype.updateBitmap = function() {
    SWDA_BattlerSpritesPosition.Sprite_Actor_updateBitmap.call(this);
	this.updateScale();
};

//角色透视（缩放图片）
Sprite_Actor.prototype.updateScale = function() {
	//修正角色无法翻转的错误
	// 镜头缩放为1时，透视额外系数为1，镜头缩放为1.3时，透视额外系数为0
	const maxCameraScale = 1.3;
	const cameraPara = 1 - ($gameScreen._zoomScaleTarget - 1) / (maxCameraScale - 1);	// 镜头无效时应该是1
	if (this.scale.x > 0) this.scale.x = 1 + (this.y - this._homeY) * 0.002 * cameraPara;
	if (this.scale.x < 0) this.scale.x = -1 - (this.y - this._homeY) * 0.002 * cameraPara;
	this.scale.y = 1 + (this.y - this._homeY) * 0.002 * cameraPara;

};

// 逃跑
Game_Actor.prototype.performEscapeSuccess = function() {
    if (this.battler()) {
      this.performEscape();
	  var escapeX = (this.battler().x - Graphics.boxWidth / 2) * 1;
	  var escapeY = 200;
      this.battler().startMove(escapeX, escapeY, 60);
    }
};

Sprite_Actor.prototype.moveToStartPosition = function() {
    if (BattleManager._bypassMoveToStartLocation) return;
    if ($gameSystem.isSideView() && this._checkAliveStatus) {
      this.startMove(0, 100, 0);
    }
};

// 角色移动（修正Y坐标，防止半截身出现）（可能导致角色无法被任意移动）
SWDA_BattlerSpritesPosition.BattleManager_ActionMoveY = BattleManager.actionMoveY;
BattleManager.actionMoveY = function(mover, targets, value) {
	const maxCameraScale = 1.2;
	const cameraPara = 1 - ($gameScreen._zoomScaleTarget - 1) / (maxCameraScale - 1);	// 镜头无效时应该是1
	const battler = mover.battler();
	let d = 0;
	if (!!battler)
		d = 10 * 0.002 * (1-cameraPara) * battler.height; // 算法不太严谨，具体懒得想了，10是强行设的值防止露出边界。
	if (mover.isActor()){
		if (!ConfigManager.battleCamera)
			return Graphics.boxHeight;
		var max = targets.length;
		//var destY = 0;
		var point = (value === 'head') ? Graphics.boxHeight : 0;
		for (var i = 0; i < max; ++i) {
			var target = targets[i];
			if (!target) continue;
			if (value === 'head') {
				point = Math.min(target.spritePosY() - target.spriteHeight(), point);
			} else if (value === 'center') {
				point += target.spritePosY() - target.spriteHeight() / 2;
			} else { // foot
				point = Math.max(target.spritePosY(), point);
			}
			if(target.isFloating())
				d = Math.max(target.floatHeight()+ 2 * target.floatRate() * target.spriteHeight(),d);
		}
		d = d / $gameScreen._zoomScaleTarget
		//destY = (value === 'center') ? point / max : point;
		var cY = BattleManager.cameraFocusY();
		if ((Graphics.boxHeight-BattleManager.cameraFocusY()) * $gameScreen._zoomScaleTarget < Graphics.boxHeight/2){
			var dY = 0;
		}else if (BattleManager.cameraFocusY() * $gameScreen._zoomScaleTarget < Graphics.boxHeight/2){
			var dY = Graphics.boxHeight * (1-1/$gameScreen._zoomScaleTarget);
		}else{
			var dY = Graphics.boxHeight * (1-1/2/$gameScreen._zoomScaleTarget) - cY;
		}
		return Graphics.boxHeight - dY + d;
	}else{
		return SWDA_BattlerSpritesPosition.BattleManager_ActionMoveY.call(this,mover, targets, value);
	}
};


SWDA_BattlerSpritesPosition.Sprite_Actor_Update = Sprite_Actor.prototype.update;
Sprite_Actor.prototype.update = function() {
	SWDA_BattlerSpritesPosition.Sprite_Actor_Update.call(this);
    if (this._actor) {
        this.updateOpacity();
    }
};


//自动更新角色不透明度（将导致无法通过动作序列更新不透明度）
SWDA_BattlerSpritesPosition.BattleManager_InitMembers = BattleManager.initMembers;
BattleManager.initMembers = function() {
	SWDA_BattlerSpritesPosition.BattleManager_InitMembers.call(this);
    this._showActorSprites = [false, false, false, false];
};

BattleManager.setShowActorSprite = function(actorId, value) {
	this._showActorSprites[actorId] = value;
};

BattleManager.showActorSprite = function(actorId) {
	return this._showActorSprites[actorId];
};

SWDA_BattlerSpritesPosition.PLUGIN_COMMAND = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
	SWDA_BattlerSpritesPosition.PLUGIN_COMMAND.call(this, command, args);
	if(command == 'showActorSprites'){
		for (let i = 1; i <= 4; i++){
			BattleManager.setShowActorSprite(i, true);
		}
	}
	if(command == 'resetActorSprites'){
		for (let i = 0; i <= 4; i++){
			BattleManager.setShowActorSprite(i, false);
		}
	}
	if(command == 'showActorSprite'){
		let actorId = parseInt(args[0]);
		BattleManager.setShowActorSprite(actorId, true);
	}
};

Sprite_Actor.prototype.updateOpacity = function(){
	if (this.meetsHideCondition()){
		this.opacity -= 16;
	}else{
		this.opacity = 255;
	}
}

Sprite_Actor.prototype.meetsHideCondition = function(){
	const actorId = this._battler._actorId;

	// 位置条件：在原点
	const posCondition = this.y === this._homeY;
	// 动作条件：为待机状态（walk/wait），且其他人未行动
	let motionCondition = (this._motion.index == 0 || this._motion.index == 1);
	// 若有人行动，则暂时隐藏
	if (!motionCondition){
		let anyoneActing = $gameParty.members().some(member => member.isWaiting() || member.isActing() || member._actionState === 'done');
		if (anyoneActing){
			motionCondition = true;
		}
	}
	// 特殊条件：不是行动目标
	const specialCondition = !(this._battler.isSelected() || this._battler.isATBCharging() || this.isAnimationPlaying() || (this._damages.length > 0));
	// 强制条件：插件指令控制
	const forcedCondition = !BattleManager.showActorSprite(actorId);

	// 所有条件均满足才可隐藏
	const result = posCondition && motionCondition && specialCondition && forcedCondition
	return result
}

// 修改入场动作
Sprite_Actor.prototype.startEntryMotion = function() {
    if (this._actor && this._actor.canMove()){
        this.startMotion('walk');
        this.startMove(0, 0, 0);
    } else if (!this.isMoving()) {
        this.refreshMotion();
        this.startMove(0, 0, 0);
    }
};

